"""
如我之前所说，文件打开后，一定要记得关闭。

但是有些时候，我们在操作文件的过程中，难免会遇到报错

如果遇到报错，那么 f.close 也许就不会正常的运行，那么文件就会一致处于 打开状态

这是一个十分可怕的事情！
"""

# 第一种方式 try...finally

# with open

"""
with xxxx as 变量名:
    your code
"""

# with open('./test.txt', 'r', encoding="utf-8") as f:
#     print(f.read())

"""
编码过程中，读者肯定会遇到一些IO类型的操作。
什么是IO？就是比如文件操作、网络请求。
往往这类操作，都需要被操作对象，比如：

文件操作，需要打开一个文件，存放在内存中
网络请求，需要一个request
数据库链接，需要一个db实例化对象还有一个游标cur
这些对象，操作前都会有一个open或connect的动作，操作结束后，都会有一个close。
在with关键字不被熟知之前，一般都是使用try-finally来进行操作前后的初始化和收尾工作。
所以本文章会专门介绍with语法，以及被操作对象如何实现。
"""

"""
with关键字在python中叫做上下文管理器，其被操作对象需要实现【上下文协议】，只有实现了这个协议，
才能被with正常的打开和关闭。
"""

# 上下文协议
"""
万物皆可对象的python，想要实现【上下文协议】当然是离不开类以及类中的魔法方法：

__enter__ with赋值会调用这个方法
__exit__ with结束会调用这个方法

"""

class TestContext():
    def __init__(self, path, mode, encoding):
        self.fileObj = open(path, mode, encoding=encoding)

    def __enter__(self):
        print("文件返回给你")
        return self.fileObj

    def __exit__(self, exc_type, exc_val, exc_tb):
        # print(f"调用了__exit__")
        print("我要被关闭咯")
        self.fileObj.close()

with TestContext('./test.txt', 'r', encoding="utf-8") as test:
    print(test.read())
    # test.close()

import pymysql

with pymysql.connect(
    host="127.0.0.1",
    user="root",
    password="123456",
    database="walkertest",
) as cn:
    ...